"""
TAPA is a dataflow HLS framework that features fast compilation, expressive
programming model and generates high-frequency FPGA accelerators.
"""

# Copyright (c) 2025 RapidStream Design Automation, Inc. and contributors.
# All rights reserved. The contributor(s) of this file has/have agreed to the
# RapidStream Contributor License Agreement.

module(name = "rapidstream-tapa")

# Bazel dependencies
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "platforms", version = "0.0.11")
bazel_dep(name = "rules_cc", version = "0.1.1")
bazel_dep(name = "rules_pkg", version = "1.0.1")
bazel_dep(name = "rules_python", version = "1.2.0")

bazel_dep(name = "toolchains_llvm", version = "1.3.0", dev_dependency = True)

http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")

llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm", dev_dependency = True)

new_local_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:local.bzl", "new_local_repository")

pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")

python = use_extension("@rules_python//python/extensions:python.bzl", "python")

# LLVM toolchain
llvm.toolchain(
    llvm_version = "16.0.0",
    stdlib = {"": "stdc++"},
)
use_repo(llvm, "llvm_toolchain")
use_repo(llvm, "llvm_toolchain_llvm")

register_toolchains(
    "@llvm_toolchain//:all",
    dev_dependency = True,
)

# Python toolchain
python.toolchain(
    configure_coverage_tool = True,
    is_default = True,
    python_version = "3.13.1",
)
use_repo(python, python_3_13 = "python_3_13_1")

# Required by tapa Python libraries
pip.parse(
    hub_name = "tapa_deps",
    python_version = "3.13.1",
    requirements_lock = "//tapa:requirements_lock.txt",
)
use_repo(pip, "tapa_deps")

# Required by tapacc
bazel_dep(name = "nlohmann_json", version = "3.11.3.bcr.1")

# Required by tapa-lib
bazel_dep(name = "rules_boost", repo_name = "com_github_nelhage_rules_boost")
git_override(
    module_name = "rules_boost",
    commit = "c3edeeb93c47ee87d01fc96aec8e48ca9449d10c",
    patch_cmds = [
        # Enable BOOST_USE_ASAN, which requires BOOST_USE_UCONTEXT.
        """sed '/name = "context",/a defines=["BOOST_USE_ASAN","BOOST_USE_UCONTEXT"],' -i boost.BUILD""",
        # Do not exclude fiber.cpp since we enable BOOST_USE_UCONTEXT
        "sed /fiber.cpp/d -i boost.BUILD",
    ],
    remote = "https://github.com/nelhage/rules_boost.git",
)

non_module_boost_repositories = use_extension("@com_github_nelhage_rules_boost//:boost/repositories.bzl", "non_module_dependencies")
use_repo(non_module_boost_repositories, "boost")

bazel_dep(name = "gflags", version = "2.2.2")

# glog must be 0.5.0 as in later versions, bazel is strictly required for
# including glog headers for the host code
bazel_dep(name = "glog", version = "0.5.0")
bazel_dep(name = "googletest", version = "1.16.0")

single_version_override(
    module_name = "glog",
    patches = ["//bazel:patches/glog/0001-Fix-unused-but-set-variable.patch"],
)

new_local_repository(
    name = "vitis_hls",
    build_file_content = """
cc_library(
    name = "include",
    hdrs = glob(["include/**/*.h"]),
    includes = ["include"],
    visibility = ["//visibility:public"],
)
    """,
    path = "/opt/tools/xilinx/Vitis/2024.2",
)

new_local_repository(
    name = "xsim_xv",
    build_file_content = """
cc_library(
    name = "svdpi",
    hdrs = glob(["include/svdpi.h"]),
    includes = ["include"],
    visibility = ["//visibility:public"],
)
    """,
    # Starting from 2024.2, Vivado has renamed rdi to xv
    path = "/opt/tools/xilinx/Vivado/2024.2/data/xsim",
)

new_local_repository(
    name = "xsim_legacy_rdi",
    build_file_content = """
cc_library(
    name = "svdpi",
    hdrs = glob(["include/svdpi.h"]),
    includes = ["include"],
    visibility = ["//visibility:public"],
)
    """,
    # Use the oldest supported version to ensure compatibility
    path = "/opt/tools/xilinx/Vivado/2022.1/data/xsim",
)

# Required by FRT
bazel_dep(name = "tinyxml2", version = "10.0.0")
bazel_dep(name = "libuuid", version = "2.39.3.bcr.1")

new_local_repository(
    name = "xilinx_xrt",
    build_file_content = """
cc_library(
    name = "xrt",
    hdrs = glob(["include/**/*.h"]),
    includes = ["include"],
    linkopts = [ "-l:libOpenCL.so.1" ],
    visibility = ["//visibility:public"],
    deps = ["@libuuid"],
)
    """,
    path = "/opt/xilinx/xrt",
)

# Required by nuitka build
bazel_dep(name = "patchelf", version = "0.18.0")

# For compatibility with GCC7
# Based on patches from https://github.com/bazelbuild/bazel-central-registry/tree/4f4bad8f463685498cf9e0a4ba45ffe9e290a853/modules/patchelf/0.18.0/patches
git_override(
    module_name = "patchelf",
    commit = "769337c227799aa60911562b6940530f4a86eb3c",
    patch_cmds = [
        # 0001-Add-MODULE.bazel.patch
        """
        cat >BUILD.bazel <<EOF
cc_binary(
    name = "patchelf",
    srcs = glob([
        "src/*.cc",
        "src/*.h",
    ]),
    copts = [
        "-std=c++17",
    ],
    local_defines = [
        "D_FILE_OFFSET_BITS=64",
    ],
    visibility = ["//visibility:public"],
)
EOF
""",
        # 0002-Add-BUILD.bazel.patch
        """
        cat >MODULE.bazel <<EOF
module(
    name = "patchelf",
    version = "0.18.0",
    compatibility_level = 0,
)
EOF
""",
    ],
    remote = "https://github.com/NixOS/patchelf.git",
)

# Build LLVM from source
LLVM_VERSION_MAJOR = 20

LLVM_VERSION_MINOR = 1

LLVM_VERSION_PATCH = 0

LLVM_VERSION = "{}.{}.{}".format(LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERSION_PATCH)

LLVM_SHA256 = "4579051e3c255fb4bb795d54324f5a7f3ef79bd9181e44293d7ee9a7f62aad9a"

# Based on patches from https://github.com/bazelbuild/bazel-central-registry/tree/707c0f939d1a801370aeb3a795e1a253a880f4f7/modules/llvm-project/17.0.3/patches
http_archive(
    name = "tapa-llvm-project",
    patch_args = ["-p1"],
    patch_cmds = [
        # 0002-Add-LLVM-Bazel-overlay-files.patch
        """
        cp -r utils/bazel/llvm-project-overlay/* .
        rm -rf utils/bazel
        """,
        # 0003-Add-MODULE.bazel.patch
        """
        cat >MODULE.bazel <<EOF
module(
    name = "llvm-project",
    version = "{}",
)

# Skylark dependencies
bazel_dep(name = "bazel_skylib", version = "1.7.1")

# Library dependencies
bazel_dep(name = "platforms", version = "0.0.11")
bazel_dep(name = "rules_cc", version = "0.1.1")
bazel_dep(name = "protobuf", version = "30.0")
EOF
        """.format(LLVM_VERSION),
        # 0004-Add-BUILD.bazel.patch
        """echo >BUILD.bazel""",
        # 0005-Add-Bazel-LLVM-targets.patch
        """echo 'llvm_targets = ["X86"]' >llvm/targets.bzl""",
        # 0006-Add-LLVM-version-vars.patch
        """
        cat >vars.bzl <<EOF
LLVM_VERSION = "{0}.{1}.{2}"
LLVM_VERSION_MAJOR = {0}
LLVM_VERSION_MINOR = {1}
LLVM_VERSION_PATCH = {2}
PACKAGE_VERSION = "{0}.{1}.{2}"
MAX_CLANG_ABI_COMPAT_VERSION = "{0}"
EOF
        """.format(LLVM_VERSION_MAJOR, LLVM_VERSION_MINOR, LLVM_VERSION_PATCH),
    ],
    patches = [
        "//bazel:patches/tapa-llvm-project/0001-Disable-zlib-zstd-mpfr-pfm-and-proto.patch",
        "//bazel:patches/tapa-llvm-project/0002-Add-TAPA-pragmas-to-Clang.patch",
        "//bazel:patches/tapa-llvm-project/0003-Wno-error.patch",
        "//bazel:patches/tapa-llvm-project/0004-Patch-missing-macro.patch",
    ],
    sha256 = LLVM_SHA256,
    strip_prefix = "llvm-project-{}.src".format(LLVM_VERSION),
    urls = ["https://github.com/llvm/llvm-project/releases/download/llvmorg-{0}/llvm-project-{0}.src.tar.xz".format(LLVM_VERSION)],
)

# Test data
http_file(
    name = "facebook_combined",
    downloaded_file_path = "facebook.txt.gz",
    sha256 = "125e84db872eeba443d270c70315c256b0af43a502fcfe51f50621166ad035d7",
    url = "https://snap.stanford.edu/data/facebook_combined.txt.gz",
)

# Required to generate `compile_commands.json`
# Usage: `bazel run :refresh_compile_commands`
bazel_dep(name = "hedron_compile_commands", dev_dependency = True)
git_override(
    module_name = "hedron_compile_commands",
    commit = "1e08f8e0507b6b6b1f4416a9a22cf5c28beaba93",
    remote = "https://github.com/hedronvision/bazel-compile-commands-extractor.git",
)
